/**
 *@filename:t_spi_m.h
 *@brief : SPI gpio driver file
 *+pach  const  function : t_spi_create.
 */
/**
 * @brief Software SPI driver
 * 
 * Timing standard: SPI Mode 0 (CPOL=0, CPHA=0)
 * - Clock idle low
 * - Data changed on falling edge, sampled on rising edge
 * - MSB first
 * - CS active low
 * 
 * SCK frequency ≈ 1 / (2 * spi_delay_time)
 * 
 * Example timing:
 *   SCK  : __/‾\__/‾\__/‾\__/‾\__/‾\__/‾\__/‾\__/‾\__
 *   MOSI : ---<D7>---<D6>---<D5>--- ... ---<D0>---
 *   MISO : ---<Rx7>--<Rx6>--<Rx5>-- ... --<Rx0>---
 *   CS   : ‾‾‾‾‾‾\__________________________/‾‾‾‾‾
 */

#ifndef _T_SPI_M_H
#define _T_SPI_M_H


#include "stdint.h"
#include "stdio.h"
#include <stdlib.h>  
#include <string.h>  
#ifdef __cplusplus
extern "C" {
#endif
#define T_NULL    NULL
#define T_FREE(p)   free(p)
#define T_MALLOC(p) malloc(p)

#define spi_delay_time 5 // spi software delay time

/* 错误码定义 */
typedef enum {
    SPI_OK = 0,
    SPI_ERR_NULL_PTR,
    SPI_ERR_TIMEOUT,
    SPI_ERR_INIT_FAIL
} spi_err_t;

typedef enum
{
	T_SPI_PIN_RESET = 0,
	T_SPI_PIN_SET = 1
} pin_value_e;
typedef void (*Tspi_pincfg_func)(void *port, uint16_t pin);
typedef void (*Tspi_delay_func)(uint32_t us);
typedef void (*Tspi_write_func)(void *port, uint16_t pin, uint8_t pin_val);
typedef uint8_t (*Tspi_read_func)(void *port, uint16_t pin);
typedef struct
{
    void *mosi_port;
	uint16_t mosi_pin; // MOSI pin

	void *miso_port;
    uint16_t miso_pin; // MISO pin

    void *sck_port;
    uint16_t sck_pin; // SCK pin

    void *cs_port;
    uint16_t cs_pin; // CS pin
	
} t_spi_gpio_t;
;
typedef enum
{
    T_SPI_NSS_Soft = 1,//会控制SPI CS信号 初始化为高  cs 信号 低有效
    T_SPI_NSS_NO = 2  //由用户自己实现CS信号，不对SPI CS信号的控制
} T_SPI_NSS_Mode;


typedef struct
{
	uint8_t T_SPI_NSS_FBIT:1;// SPI CS信号控制位
	Tspi_pincfg_func hwcfgOut_func; // cfg out
	Tspi_pincfg_func hwcfgIn_func;
	Tspi_delay_func delay_func; // cfg delay
	Tspi_write_func write_func;
	Tspi_read_func read_func;
	void *arg;
	const t_spi_gpio_t *hw_gpio;
} t_spi_t;

t_spi_t *t_spi_create(void *arg,
                    T_SPI_NSS_Mode mode,
					Tspi_pincfg_func cfgout_func,
					Tspi_pincfg_func cfgin_func,
					Tspi_delay_func delay_func,
					Tspi_write_func spi_w_func,
					Tspi_read_func spi_r_func,
					const t_spi_gpio_t *hw_gpio);
spi_err_t t_spi_send_byte(t_spi_t *me, uint8_t *tdata, uint16_t tlen,uint16_t ttimeout_ms);
spi_err_t t_spi_read_byte(t_spi_t *me, uint8_t *rdata, uint16_t rlen,uint16_t rtimeout_ms);
spi_err_t t_spi_SendRead_byte(t_spi_t *me, uint8_t *tdata,uint8_t *rdata,uint16_t len,uint16_t timouts);
#ifdef __cplusplus
}
#endif

#endif